﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Security.Cryptography;

namespace Meraz.Core.Model
{
    public class Member: IEquatable<Member>
    {
        public Member() {
            DateTime now = DateTime.Now;
            CreationDate = now;
            LastActivityDate = now;
        }
        #region Properties

        public int ID { get; set; }
        public string ProviderUserKey { get; set; }
        public string ApplicationName { get; set; }
        public string Comment { get; set; }
        public DateTime CreationDate { get; set; }

        public long CreationDateTicks { get { return CreationDate.Ticks; } set { CreationDate = new DateTime(value); } }

        public string Email { get; set; }
        public int FailedPasswordAnswerAttemptCount { get; set; }
        public DateTime FailedPasswordAnswerAttemptWindowStart { get; set; }

        public long FailedPasswordAnswerAttemptWindowStartTicks { get { return FailedPasswordAnswerAttemptWindowStart.Ticks; } set { FailedPasswordAnswerAttemptWindowStart = new DateTime(value); } }

        public int FailedPasswordAttemptCount { get; set; }
        public DateTime FailedPasswordAttemptWindowStart { get; set; }

        public long FailedPasswordAttemptWindowStartTicks { get { return FailedPasswordAttemptWindowStart.Ticks; } set { FailedPasswordAttemptWindowStart = new DateTime(value); } }

        public bool IsApproved { get; set; }
        public bool IsLockedOut { get; set; }
        public bool IsOnline { get; set; }
        public DateTime LastActivityDate { get; set; }
        public DateTime LastLockoutDate { get; set; }
        public DateTime LastLoginDate { get; set; }
        public DateTime LastPasswordChangedDate { get; set; }

        public long LastActivityDateTicks { get { return LastActivityDate.Ticks; } set { LastActivityDate = new DateTime(value); } }
        public long LastLockoutDateTicks { get { return LastLockoutDate.Ticks; } set { LastLockoutDate = new DateTime(value); } }
        public long LastLoginDateTicks { get { return LastLoginDate.Ticks; } set { LastLoginDate = new DateTime(value); } }
        public long LastPasswordChangedDateTicks { get { return LastPasswordChangedDate.Ticks; } set { LastPasswordChangedDate = new DateTime(value); } }

        public string Password { get; set; }
        public string PasswordAnswer { get; set; }
        public string PasswordQuestion { get; set; }
        public string ProviderName { get; set; }
        public string Salt { get; set; }
        public string UserName { get; set; }


        public MembershipUser User
        {
            get
            {
                MembershipUser user = new MembershipUser(
                    ProviderName,
                    UserName,
                    ProviderUserKey,
                    Email,
                    PasswordQuestion,
                    Comment,
                    IsApproved,
                    IsLockedOut,
                    CreationDate,
                    LastLoginDate,
                    LastActivityDate,
                    LastPasswordChangedDate,
                    LastLockoutDate);
                return user;
            }
        } 
        #endregion

        public bool IsEmailValid()
        {
            if (string.IsNullOrWhiteSpace(Email))
                return false;

            return true;
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            return Equals((Member)obj);
        }

        public override int GetHashCode()
        {
            return ApplicationName.GetHashCode() 
                ^ UserName.GetHashCode();
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("{");
            builder.AppendFormat("{0}: {1}, ", "ID", ID);
            builder.AppendFormat("{0}: '{1}', ", "ApplicationName", ApplicationName);
            builder.AppendFormat("{0}: '{1}'", "UserName", UserName);
            builder.Append("}");
            return builder.ToString();
        }

        public static string CreateSalt(int size)
        {
            //Generate a cryptographic random number.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[size];
            rng.GetBytes(buff);

            // Return a Base64 string representation of the random number.
            return Convert.ToBase64String(buff);
        }

        public static string CreatePasswordHash(string pwd, string salt)
        {
            string saltAndPwd = String.Concat(pwd, salt);
            string hashedPwd =
             FormsAuthentication.HashPasswordForStoringInConfigFile(
             saltAndPwd, "sha1");

            return hashedPwd;
        }


        #region IEquatable<Member> Members

        public bool Equals(Member other)
        {
            if (other == null)
                return false;
            if (this.ID == 0 || other.ID == 0)
            {
                if (!this.ApplicationName.Equals(other.ApplicationName))
                    return false;
                return this.UserName.Equals(other.UserName);
            }
            return this.ID.Equals(other.ID);
        }

        #endregion
    }
}
